import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Stack;

/**
 * Created with IntelliJ IDEA.
 * Description：
 * User：user
 * DATE:2021-11-01
 * Time:15:04
 */
    //集合框架及背后的数据结构
    //顺序表
    //链表 单链表 双向链表
    //ArrayList 代表的就是顺序表不用自定义直接使用
    //LinkedList 代表就是链表
    //每一个集合的背后就是一个数据结构


    //java collection framework  java集合框架
    //interface 接口
    //abstract 抽象类
    //class    实现类
    //接口和接口的关系：extends 扩展接口
    //接口和类的关系：class 继承类
    //Iterable  迭代器
    //Collection
    //List Quene Set(集合)
    //Vector    Stactk  ArrayList  LinkedList(双向链表)
    //PriorityQueue  优先级队列
    //HashSet   HashMap(哈希表)
    //TreeSet   TreeMap(二叉搜索树)


    //工具类：Arrays Collections
    //通过Collection接口可以实现下面的所有类,多态向上转型，运行时绑定


    //泛型 java中的一种语法，比较难理解，但是对于泛型我们也只是了解即可

    //泛型类
    //<T>当前类是一个泛型类
    //1.可以进行类型的检查
    //2.可以进行类型的自动转换

//泛型是如何编译的
//擦除机制 会将所有的T擦除为Object
//<里面的内容> //1.可以进行类型的检查 2.可以进行类型的自动转换
//泛型是作用与编译期间的一种机制，在运行期间没有泛型这个概念
//泛型在运行期间是利object达到的效果



class  MyArrayList2<T>{//规定类型  泛型
    public T[] elem;
    public int usedSize;

    public MyArrayList2(){
        //this.elem = new T[10];错误写法不能这样写
        this.elem = (T[])new Object[10];//虽然所有的T都被转为了Object但是无法确定具体是哪个只能先构造object再转化为T类型
        //T拥有了Object的特性什么都可以放但是不能说直接替换成了Objecct，java数组比较复杂
    }

    public void add(T val){
        this.elem[this.usedSize++] = val;

    }
    public T getPos(int pos){
        return this.elem[pos];
    }

}

class  MyArrayList{
    public Object[] elem;
    public int usedSize;

    public MyArrayList(){
        this.elem = new Object[10];
    }

    public void add(Object val){
        this.elem[this.usedSize++] = val;

    }
    public Object getPos(int pos){
        return this.elem[pos];
    }

}
class Person{

}
public class TestDemo2 {

    public static void main(String[] args) {
        Object object = null;
        Integer integer = (Integer) object;//简单的数据类型单个进行强制类型转换不报错
        //若果是object数组是无法进行数据转化的
        //本质上来说确实是将T替换为了Object，但是由于历史原因，jvm对于数组的实现，就是不可以对数组进行强制类型转换
        Integer[] integers = new Integer[5];
        //Long[] longs = (Long[]) integers;//无法强转
    }

    public static void main5(String[] args) {
        Integer[] array = new Integer[10];
        Object[] objects = array;

        Object[] array2 = new Object[10];
        //Integer[] objects2 = array2;//会报错Object类型的数组是无法转换为Ineter数组的
        Integer[] objects3 = (Integer[]) array;

    }

    public static void main4(String[] args) {
        Person person = new Person();
        System.out.println(person);//普通类打印对象为类型加地址
        MyArrayList2 myArrayList2 = new MyArrayList2();
        System.out.println(myArrayList2);//<>中的数据不参与类型的组成
        MyArrayList myArrayList = new MyArrayList();
        System.out.println(myArrayList);
    }
    public static void main3(String[] args) {
        MyArrayList2<Integer> myArrayList = new MyArrayList2<>();
        myArrayList.add(1);
        myArrayList.add(2);
        //myArrayList.add(1.1);会报错因为已经指定了放整数
        //myArrayList.add("hah");会报错因为制定了放整数
        int val = myArrayList.getPos(0);//可以直接接受不会报错不用转型
        MyArrayList2<String> myArrayList2 = new MyArrayList2<>();
        myArrayList2.add("1");
        myArrayList2.add("2");
        myArrayList2.add("3");
        String str = myArrayList2.getPos(0);//不会报错不用进行类型转换
    }

    public static void main2(String[] args) {
        MyArrayList myArrayList = new MyArrayList();//此时只放整数
        myArrayList.add(1);
        myArrayList.add(2);
        myArrayList.add("高博");
        int val = (int)myArrayList.getPos(0);//必须强转因为是Object，比较麻烦

    }

    public static void main1(String[] args) {
        //向上转型
        Collection<String> collection = new ArrayList<>();//指定只能放字符串
        Collection<Integer> collection4 = new ArrayList<>();//不可以放int普通类型需要放的是Interger<>
        Collection collection2 = new LinkedList<>();
        Collection collection3 = new Stack<>();
        //大杂混这种写法不太好
        /*collection.add(1);
        collection.add("gb");*/
    }

}
